package org.example;

import org.example.utils.fh.CtsSdk;
import org.example.utils.fh.ToolKits;
import com.sun.jna.Memory;
import com.sun.jna.Pointer;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.concurrent.BlockingQueue;

import static org.example.utils.fh.CtsSdk.enSdkCbType.*;

public class Test {

    static CtsSdk netSinkLib = CtsSdk.COMMON_INSTANCE;
    private static int m_nTermCnt = 0;
    private static ArrayList<CtsSdk.TSdkEventTermRegister> m_TermList = new ArrayList<CtsSdk.TSdkEventTermRegister>();
    private static ArrayList<Integer> m_TermState = new ArrayList<Integer>();
    private static int index = -1;
    private static int group = -1;


    public static void main(String[] args) throws InterruptedException, UnsupportedEncodingException {
        File file = new File("a.mp3");
        System.out.println(file.length());

        netSinkLib.TSDK_DeInit();
        OnCtsSdkCallBack onCtsSdkCallBack = new OnCtsSdkCallBack();
        boolean a = true;
        int b = 0x12345678;
        int tsdk_init = netSinkLib.TSDK_Init(onCtsSdkCallBack, a, b);
        if (tsdk_init == 0) {
            System.out.println("SDK 初始化成功！");
        } else {
            System.out.println("SDK 初始化失败！错误代码:" + tsdk_init);
        }

        int sound = 30;
        // 测试音量
        while (tsdk_init == 0) {
            if (!m_TermList.isEmpty()) {
                for (CtsSdk.TSdkEventTermRegister tSdkEventTermRegister : m_TermList) {
                    netSinkLib.TSDK_Req_GetAudLevel(tSdkEventTermRegister.dwTermID);
                    if (sound < 1000) {
                        CtsSdk.TSdkAudioLevel tSdkAudioLevel = new CtsSdk.TSdkAudioLevel();
                        if (sound % 10 == 0){
                            tSdkAudioLevel.eAmpLevel = CtsSdk.enSdkAudAmpLevel.SDK_AAMP_LEVEL_10;
                        }
                        if (sound % 10 == 1){
                            tSdkAudioLevel.eAmpLevel = CtsSdk.enSdkAudAmpLevel.SDK_AAMP_LEVEL_10;
                        }
                        tSdkAudioLevel.eCapLevel = CtsSdk.enSdkAudCapLevel.SDK_ACAP_LEVEL_1;
                        tSdkAudioLevel.eAmpLevel = CtsSdk.enSdkAudAmpLevel.SDK_AAMP_LEVEL_2;
                        tSdkAudioLevel.eCapTalkLevel = CtsSdk.enSdkAudCapTalkLevel.SDK_ACAP_TALK_LEVEL_1;
                        int i = netSinkLib.TSDK_Req_SetAudLevel(tSdkEventTermRegister.dwTermID, tSdkAudioLevel);
                        System.out.println(i);
                    }
                    sound = sound + 1;
                }

//                if (index <= m_nTermCnt) {
//                    bfmp3();
//                }
                // 调节音量
                // group 广播分组
                if (group != -1) {

                }
            }
            System.out.println("============");
            Thread.sleep(2000L);
        }
    }


    private static class OnCtsSdkCallBack implements CtsSdk.OnCtsSdkCallBack {
        private byte[] G_buffer = new byte[0];
        private BlockingQueue<byte[]> queue;

        public byte[] byteMerger(byte[] a, byte[] b) {
            byte[] temp = new byte[a.length + b.length];
            System.arraycopy(a, 0, temp, 0, a.length);
            System.arraycopy(b, 0, temp, a.length, b.length);
            return temp;
        }

        @Override
        public int invoke(int eCbType, Pointer pParam, int dwSize, int usr_data) throws IOException, ClassNotFoundException {
            System.out.println(eCbType);
            switch (eCbType) {
                case CB_Event_TermRegister:
                    System.out.println("注册");
                    CtsSdk.TSdkEventTermRegister tSdkTermRegister = new CtsSdk.TSdkEventTermRegister();
                    ToolKits.GetPointerDataToStruct(pParam, 0, tSdkTermRegister);
                    int i;
                    for (i = 0; i < m_nTermCnt; i++) {
//            			if(m_TermList.get(i).dwTermID == tSdkTermRegister.dwTermID)
//        					break;
                    }
                    if (i < m_nTermCnt) {
                        // 更新
                        m_TermList.add(tSdkTermRegister);
                    } else {
                        // 注册
                        if (m_nTermCnt >= CtsSdk.MAX_TERM_COUNT)
                            return -1; // 返回 0 代表注册成功，否则代表注册失败 !!!
                        m_TermList.add(tSdkTermRegister);
                        m_TermState.add(CtsSdk.enSdkDevState.TSDK_DEV_STATE_OFFLINE);
                        m_nTermCnt = 1;
                    }
                    return 0;
                case CB_Event_TermConnect:
                    System.out.println("连接");
                    CtsSdk.TSdkEventTermConnect tSdkTermConnect = new CtsSdk.TSdkEventTermConnect();
                    ToolKits.GetPointerDataToStruct(pParam, 0, tSdkTermConnect);

//                	System.out.println(">>> %s 请求连接：终端ID:%X , %s视频 , MAC地址:%02X-%02X-%02X-%02X-%02X-%02X , IP地址:%s , 名称:%s",
//                			tSdkTermConnect.eTermType, tSdkTermConnect.dwTermID, tSdkTermConnect.bHasVideo ? "有" : "无",
//                			"", tSdkTermConnect.TermIp, tSdkTermConnect.TermName);


                    System.out.println("终端ID:" + tSdkTermConnect.dwTermID);
                    System.out.println("名称:" + new String(tSdkTermConnect.TermName));
                    System.out.println("名称:" + new String(tSdkTermConnect.TermIp));

//                	System.out.println("连接dwTermID:"+tSdkTermConnect.dwTermID);

                    // TODO 没有注册事件有连接事件
                    if (m_TermList.isEmpty()) {
                        CtsSdk.TSdkEventTermRegister tSdkEventTermRegister = new CtsSdk.TSdkEventTermRegister();
                        tSdkEventTermRegister.TermName = tSdkTermConnect.TermName;
                        tSdkEventTermRegister.TermIp = tSdkTermConnect.TermIp;
                        tSdkEventTermRegister.TermMac = tSdkTermConnect.TermMac;
                        tSdkEventTermRegister.dwTermID = tSdkTermConnect.dwTermID;
                        m_TermList.add(tSdkEventTermRegister);
                    }
                    index = 0;
                    for (index = 0; index < m_nTermCnt; index++) {
                        if (m_TermList.isEmpty()) continue;
                        if ((m_TermList.get(index).dwTermID == tSdkTermConnect.dwTermID)) {
                            break;
                        }
                    }

                    if (index <= m_nTermCnt) {
                        bfmp3();
                        return 0; // 返回 0 代表允许连接，否则代表不允许 !!!
                    } else {
                        // 未注册
                        return -1; // 返回 0 代表允许连接，否则代表不允许 !!!
                    }


                case CB_Data_TermMp3L:
                    CtsSdk.TSdkDataTermMp3L tSdkDataTermMp3L = new CtsSdk.TSdkDataTermMp3L();
                    ToolKits.GetPointerDataToStruct(pParam, 0, tSdkDataTermMp3L);
                    Pointer pMp3Data = tSdkDataTermMp3L.pMp3Data;
                    if (pMp3Data == null) {
                        return 0;
                    }

                    byte[] recive_buf = pMp3Data.getByteArray(0, tSdkDataTermMp3L.nDataSize);
                    //判断缓存数组是否超过2048字节，如果超出则写入队列，然后清空数组
                    int gBufferLen = G_buffer.length;
                    int reciveBufferLen = recive_buf.length;
                    int totalLen = gBufferLen + reciveBufferLen;

                    if (gBufferLen + reciveBufferLen >= 2048) {
                        byte[] temBuffer01 = new byte[2048 - gBufferLen];
                        System.arraycopy(recive_buf, 0, temBuffer01, 0, 2048 - gBufferLen);
                        G_buffer = byteMerger(G_buffer, temBuffer01);
                        //写入队列
                        System.out.println("bufferTemp2048:" + G_buffer.length);

                        //释放数组
                        G_buffer = new byte[0];
                        byte[] temBuffer02 = new byte[totalLen - 2048];
                        System.arraycopy(recive_buf, 2048 - gBufferLen, temBuffer02, 0, totalLen - 2048);
                        G_buffer = byteMerger(G_buffer, temBuffer02);
                        System.out.println("bufferTemp:" + G_buffer.length);
                    } else {
                        G_buffer = byteMerger(G_buffer, recive_buf);
                    }
                    queue.add(G_buffer);
                    return 0;
                case CB_Asw_GetAudLevel: // 获取音量级别
                    CtsSdk.TSdkAudioLevel tSdkAudioLevel = new CtsSdk.TSdkAudioLevel();
                    ToolKits.GetPointerDataToStruct(pParam, 0, tSdkAudioLevel);
                    int ampLevel = tSdkAudioLevel.eAmpLevel;
                    System.out.println(String.format("响应获取音量级别：%s", ampLevel));
                case CB_Data_TermMp3R:
                    System.out.println("____________________");
                    break;
                case CB_Data_TermPcmL:

                    break;
                case CB_Data_TermPcmR:
                    break;
                case CB_Data_TermAudio://播放音频
                    break;
                case CB_Asw_SetAudLevel://播放音频
                    break;
                case CB_Post_TermState://202 // 推送终端状态
                    CtsSdk.TSdkPostTermState tSdkTermState = new CtsSdk.TSdkPostTermState();
                    ToolKits.GetPointerDataToStruct(pParam, 0, tSdkTermState);
                    System.out.println("tSdkTermState.dwTermID:" + tSdkTermState.dwTermID);
                    System.out.println("tSdkTermState.eTermState:" + tSdkTermState.eTermState);
                    System.out.println("tSdkTermState.AlmOutMask:" + tSdkTermState.AlmOutMask);
                    System.out.println("tSdkTermState.AlmOutState:" + tSdkTermState.AlmOutState);
                    break;
                case CB_Post_TermSos://202 // 推送终端状态
                    CtsSdk.TSdkPostTermSos tSdkTermSos = new CtsSdk.TSdkPostTermSos();
                    ToolKits.GetPointerDataToStruct(pParam, 0, tSdkTermSos);
                    System.out.println("tSdkTermSos.dwTermID:" + tSdkTermSos.dwTermID);
                    System.out.println("tSdkTermSos.nSosType:" + tSdkTermSos.nSosType);
                    break;
                case CB_Post_Mp3PlayFinish://204; 推送MP3文件播放结束通知
                    if (index >= 0) {
                        // TODO 完成当个文件播放后接着播放
                        bfmp3();
//                        netSinkLib.TSDK_StopBroadMp3(index);
                    }
                    break;

            }
            return 0;
        }
    }

    private static void bfmp3() throws UnsupportedEncodingException {
        if (index < 0) {
            return;
        }
        if (m_TermList.isEmpty()) return;

        CtsSdk.TSdkGroupTermList pTermList = new CtsSdk.TSdkGroupTermList();
        pTermList.TermList[index] = m_TermList.get(index).dwTermID;
        /**
         * 个人理解：创建广播分组 指定那些喇叭广播播放
         * 创建TSDK_StartBroadMp3 开启了广播
         * 	  TSDK_BroadMp3File 播放文件
         * 这个可以一直循环单个文件吗
         */
        int nResult = netSinkLib.TSDK_SetupGroup(index + 1, pTermList);
        group = nResult;
        if (nResult != 0) {
            System.out.println("创建分区失败！错误代码:" + nResult);
        } else {
            System.out.println("创建分区成功");
            int nMp3 = netSinkLib.TSDK_StartBroadMp3(index + 1);//开启广播MP3
            if (nMp3 == 0) {
                System.out.println("开启广播MP3成功");
                File file = new File("audio2_10s.mp3");
//                File file = new File("a.mp3");
                System.out.println(file.length());
                byte[] filePathBytes = file.getAbsolutePath().getBytes("GBK");
                Pointer porMp3File=new Memory(filePathBytes.length + 1);
                // 直接写入字节数据到内存
                porMp3File.write(0, filePathBytes, 0, filePathBytes.length);
                // 手动添加字符串结束符，因为C语言字符串以null结尾
                porMp3File.setByte(filePathBytes.length, (byte)0);

                int nMp3Filet = netSinkLib.TSDK_BroadMp3File(index + 1, porMp3File);
                if (nMp3Filet != 0) {
                    System.out.println("广播MP3文件失败！错误代码:" + nMp3Filet);
                }

            } else {

                System.out.println("开启广播MP3失败！错误代码: " + nMp3);
                if (nMp3 == -807)
                    netSinkLib.TSDK_StopBroadMp3(index + 1);

            }
        }
    }

    // SDK GBK编码
    private static String getGbkStr(String str) throws UnsupportedEncodingException {
        return new String(str.getBytes(), "GBK");
    }


}
